﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CrossGenLogic
{
    public class Crossword
    {
        private int width, height;
        private List<GridElement> grid;
        private List<VocElement> vocabulary;
        private CharWithCount[,] field;

        public Crossword(List<GridElement> grid, List<VocElement> vocabulary, int width, int height)
        {
            this.height = height;
            this.width = width;
            this.grid = grid;
            this.vocabulary = vocabulary;
            field = SetChars();
        }

        private CharWithCount[,] SetChars()
        {
            CharWithCount[,] newfield = new CharWithCount[this.height, this.width];
            for (int i = 0; i < grid.Count; i++)
                for (int j = 0; j < grid[i].Length; j++)
                {
                    newfield[grid[i].Y + grid[i].dy() * j, grid[i].X + grid[i].dx() * j] = new CharWithCount(false);
                }
            for (int i = 0; i < height; i++)
                for (int j = 0; j < width; j++)
                    if (newfield[i, j] == null) newfield[i, j] = new CharWithCount(true);
            return newfield;
        }

        public int Height
        {
            get
            {
                return height;
            }
        }

        public int Width
        {
            get
            {
                return width;
            }
        }

        public void DecreaseCount(int i, int j)
        {
            field[j, i].DecreaseCount();
        }

        public char GetCharWithCount(int i, int j)
        {
            return field[j, i].Char;
        }

        public bool GetCharType(int i, int j)
        {
            return field[j, i].IsEmpty;
        }

        public void SetCharWithCount(int i, int j, char letter)
        {
            field[j, i].SetChar(letter);
        }

        public GridElement GetGEByNumber(int i)
        {
            return grid[i];
        }

        public VocElement GetWordByNumber(int i)
        {
            return vocabulary[i];
        }

        public int WordsInCross()
        {
            return grid.Count;
        }

        public int WordsInVoc()
        {
            return vocabulary.Count;
        }

        private int CompareByLength(VocElement x, VocElement y)
        {
            if (x.Length > y.Length) return 1;
            if (x.Length == y.Length) return 0;
            else return -1;
        }

        public void SortVocabulary()
        {
            vocabulary.Sort(CompareByLength);
        }

        public void SetBusy(int i, bool b)
        {
            vocabulary[i].Busy = b;
        }

        private bool isGridContain(int gridnum, int x, int y)
        {
            if (grid[gridnum].dx() == 1 && grid[gridnum].Y == y)
            {
                if (x >= grid[gridnum].X && x < grid[gridnum].X + grid[gridnum].Length)
                    return true;
            }
            if (grid[gridnum].dy() == 1 && grid[gridnum].X == x)
            {
                if (y >= grid[gridnum].Y && y < grid[gridnum].Y + grid[gridnum].Length)
                    return true;
            }
            return false;
        }

        public void SetIntersection()
        {
            for (int i = 0; i < grid.Count; i++)
            {
                for (int k = 0; k < grid[i].Length; k++)
                {
                    for (int l = 0; l < grid.Count; l++)
                    {
                        if (i != l)
                        {
                            if (isGridContain(l, grid[i].X + grid[i].dx() * k, grid[i].Y + grid[i].dy() * k))
                            {
                                grid[i].AddIntersection(l);
                            }
                        }
                    }
                }
            }
        }

        public int GetFirstGE()
        {
            int max = 0;
            for (int i = 1; i < grid.Count; i++)
            {
                if (grid[i].GetInterCount() > grid[max].GetInterCount()) max = i;
            }
            return max;
        }

        public bool IsAllInetFill(GridElement GE)
        {
            for (int i = 0; i < GE.GetInterCount(); i++)
            {
                if (!grid[GE.GetIntersection()[i]].IsFill) return false;
            }
            return true;
        }
    }
}
